package org.igeek.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * @package org.igeek.proxy.jdk
 * @Description 动态代理模式
 * @Author LittlePunk [296526219@qq.ccom]
 * @Version 2022.1
 * @Date 2023/11/13 21:23
 */
public class JdkProxy {
    //1.创建目标对象
    private OrderInterface target;

    public JdkProxy(OrderInterface target) {
        this.target = target;
    }
    //2.获取代理对象
    public OrderInterface getProxy(){
        //3.创建代理对象
        OrderInterface proxy=null ;
        //4.获取执行器
        InvocationHandler handler = new InvocationHandler() {

            //执行方法：进行功能增强
            /**
             * 将当前编写的功能 作用在目标方法之上
             * @param proxy 代理对象，一般不使用
             * @param method  目标类中的目标方法对象
             * @param args 目标类中的目标方法的形参列表
             * @return 目标类中的目标方法的执行结果
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                String methodName = method.getName();
                System.out.println("开始日志追踪:method=" + methodName + ",args=" + Arrays.toString(args));
                long start = System.currentTimeMillis();
                //执行核心业务
                if ("order".equals(method.getName())) {
                    Object result = method.invoke(target, args);
                    System.out.println("已经接订单在送去的路上");
                    long end = System.currentTimeMillis();
                    System.out.println("结束日志追踪:method=" + methodName + ",耗时=" + (end - start) );
                    return result + "买了一杯珍珠奶茶";

                } else {
                    long end = System.currentTimeMillis();
                    System.out.println("结束日志追踪:method=" + methodName + ",耗时=" + (end - start));
                    return method.invoke(target, args);
                    //使用method反射调用，在原对象中执行方法，并不改变逻辑，也就是说原封不动调用原来的逻辑
                }
            }
        };
        //获取目标类的 类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();
        //获取目标类实现的接口
        Class<?>[] interfaces = target.getClass().getInterfaces();
        //利用jdk的api创建代理对象
        proxy = (OrderInterface) Proxy.newProxyInstance(classLoader,interfaces,handler);
        return proxy;
    }
}
